package com.project.controller;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.project.entity.OutOrderInfo;
import com.project.service.OutOrderInfoService;
import com.project.util.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.checkerframework.checker.units.qual.A;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.spring.web.json.Json;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@RestController
@Api(tags = "销售单详情接口")
@RequestMapping("outOrderInfo")
public class OutOrderInfoController {
    @Autowired
    private OutOrderInfoService outOrderInfoService;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private RLock rLock;

    @ApiOperation(value = "按销售单ID查询销售详情")
    @GetMapping("findByOutOrderId/{outOrderId}")
    public List<OutOrderInfo> findByOutOrderId(@PathVariable("outOrderId") Integer outOrderId) throws InterruptedException {
//        String key = String.valueOf(outOrderId);
//        if (redisTemplate.hasKey(key)){
//            ValueOperations<String,Object> operations = redisTemplate.opsForValue();
//            String json = (String) operations.get(key);
//            return JSONObject.parseArray(json,OutOrderInfo.class);
//        }else {
//            List<OutOrderInfo> outOrderInfoList =  outOrderInfoService.findByOutOrderId(outOrderId);
//            if (outOrderInfoList.size() > 0){
//                redisTemplate.opsForValue().set(key, JSON.toJSONString(outOrderInfoList),StringUtil.CACHE_TIME_MAX,TimeUnit.SECONDS);
//                return outOrderInfoList;
//            }
//            return new ArrayList<>();
//        }
        String key = String.valueOf(outOrderId);
        if (redisTemplate.hasKey(key)) {
            //  存在缓存
            ValueOperations<String, Object> operations = redisTemplate.opsForValue();
            String json = (String) operations.get(key);
            return JSONObject.parseArray(json, OutOrderInfo.class);
        } else {
            //  竞争锁
            boolean bl = rLock.tryLock(0,10,TimeUnit.SECONDS);
            if (bl){
                //  不存在缓存
                List<OutOrderInfo> outOrderInfoList =  outOrderInfoService.findByOutOrderId(outOrderId);
                //  防止缓存雪崩
                //  每一个条件的hash值
                long codeNum = key.hashCode();
                //  随机获取到一个值 作为缓存时间
                int time = (int)codeNum % StringUtil.CACHE_TIME_MAX;
                //如果随机值小于最小缓存时间，那么该随机值就赋值为最小缓存时间值
                if (time < StringUtil.CACHE_TIME_MIN){
                    time = StringUtil.CACHE_TIME_MIN;
                }
                if (outOrderInfoList.size() == 0){
                    //  所查询的数据库对象值为null 将缓存时间变短 （防止故意攻击）
                    redisTemplate.opsForValue().set(key, JSON.toJSONString(outOrderInfoList),StringUtil.CACHE_TIME_MIN,TimeUnit.SECONDS);
                }else {
                    redisTemplate.opsForValue().set(key, JSON.toJSONString(outOrderInfoList),time,TimeUnit.SECONDS);
                    return outOrderInfoList;
                }
                rLock.unlock();//   释放锁
            }else {
                //  没有竞争到锁
                Thread.sleep(500);//    休眠500毫秒
                this.findByOutOrderId(outOrderId);//   重新竞争锁
            }
        }
        return new ArrayList<>();
    }
}
